from fastapi import APIRouter, UploadFile, File, HTTPException, Response
from fastapi.responses import StreamingResponse
from typing import List
import io
from app.services import pdf_service
from app.models.response import ApiResponse
from app.utils.file_utils import validate_file_type
from app.config import settings

router = APIRouter()

@router.post(
    "/ocr",
    response_model=ApiResponse,
    summary="PDF/图片OCR识别",
    description="""
    将PDF文档或图片中的文字通过OCR技术识别出来。
    支持的文件格式：PDF、PNG、JPG、JPEG
    支持的识别语言：中文+英文(默认)、仅中文、仅英文
    """,
    response_description="返回识别出的文本内容"
)
async def ocr_pdf(
    file: UploadFile = File(..., description="要识别的PDF或图片文件"),
    lang: str = settings.OCR_LANGUAGES["中文+英文"]
):
    """
    PDF文档或图片OCR识别
    
    Args:
        file: 上传的PDF或图片文件
        lang: OCR识别的语言，默认为中文+英文
    
    Returns:
        ApiResponse: 包含识别结果的响应对象
    
    Raises:
        400: 文件格式不支持或处理失败
    """
    try:
        # 验证文件类型
        if not validate_file_type(file.filename, ['.pdf', '.png', '.jpg', '.jpeg']):
            return ApiResponse(
                code=400,
                message="不支持的文件类型"
            )

        content = await file.read()
        result = await pdf_service.perform_ocr(content, file.filename, lang)
        
        return ApiResponse(data={"text": result})
    except Exception as e:
        return ApiResponse(code=400, message=str(e))

@router.post(
    "/to-word",
    summary="PDF转Word",
    description="""
    将PDF文档转换为可编辑的Word文档。
    - 保持文本内容和基本格式
    - 输出为.docx格式
    - 支持多页PDF转换
    """,
    response_description="返回转换后的Word文档"
)
async def convert_to_word(
    file: UploadFile = File(
        ...,
        description="要转换的PDF文件",
        max_size=settings.MAX_FILE_SIZE
    )
):
    """
    PDF转Word文档
    
    Args:
        file: 上传的PDF文件，大小限制10MB
    
    Returns:
        StreamingResponse: Word文档的文件流
    
    Raises:
        400: 文件格式不支持或转换失败
    """
    try:
        # 验证文件类型
        if not validate_file_type(file.filename, ['.pdf']):
            return ApiResponse(
                code=400,
                message="请上传PDF文件"
            )

        content = await file.read()
        docx_bytes = await pdf_service.pdf_to_word(content)
        
        # 返回文件流
        return StreamingResponse(
            io.BytesIO(docx_bytes),
            media_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document",
            headers={
                "Content-Disposition": f'attachment; filename="converted.docx"'
            }
        )
    except Exception as e:
        return ApiResponse(code=400, message=str(e))

@router.post(
    "/to-ppt",
    summary="PDF转PPT",
    description="""
    将PDF文档转换为PowerPoint演示文稿。
    - 每页PDF转换为一页幻灯片
    - 保持原始图像质量
    - 支持多页转换
    """,
    response_description="返回转换后的PPT文档"
)
async def convert_to_ppt(
    file: UploadFile = File(
        ...,
        description="要转换的PDF文件",
        max_size=settings.MAX_FILE_SIZE
    )
):
    """
    PDF转PPT演示文稿
    
    Args:
        file: 上传的PDF文件，大小限制10MB
    
    Returns:
        StreamingResponse: PPT文档的文件流
    
    Raises:
        400: 文件格式不支持或转换失败
    """
    try:
        if not validate_file_type(file.filename, ['.pdf']):
            return ApiResponse(
                code=400,
                message="请上传PDF文件"
            )

        content = await file.read()
        pptx_bytes = await pdf_service.pdf_to_ppt(content)
        
        return StreamingResponse(
            io.BytesIO(pptx_bytes),
            media_type="application/vnd.openxmlformats-officedocument.presentationml.presentation",
            headers={
                "Content-Disposition": f'attachment; filename="converted.pptx"'
            }
        )
    except Exception as e:
        return ApiResponse(code=400, message=str(e))

@router.post(
    "/images-to-pdf",
    summary="图片转PDF",
    description="""
    将多张图片合并为一个PDF文档。
    - 支持PNG、JPG、JPEG格式
    - 保持原始图片质量
    - 按上传顺序合并
    - 支持多张图片批量处理
    """,
    response_description="返回合并后的PDF文档"
)
async def convert_images_to_pdf(
    files: List[UploadFile] = File(
        ...,
        description="要转换的图片文件列表",
        max_size=settings.MAX_FILE_SIZE
    )
):
    """
    图片转PDF文档
    
    Args:
        files: 上传的图片文件列表，每个文件大小限制10MB
    
    Returns:
        StreamingResponse: PDF文档的文件流
    
    Raises:
        400: 文件格式不支持或转换失败
    """
    try:
        # 验证所有文件
        for file in files:
            if not validate_file_type(file.filename, ['.png', '.jpg', '.jpeg']):
                return ApiResponse(
                    code=400,
                    message=f"不支持的文件类型: {file.filename}"
                )

        contents = []
        for file in files:
            content = await file.read()
            contents.append(content)
            
        pdf_bytes = await pdf_service.images_to_pdf(contents)
        
        return StreamingResponse(
            io.BytesIO(pdf_bytes),
            media_type="application/pdf",
            headers={
                "Content-Disposition": f'attachment; filename="converted.pdf"'
            }
        )
    except Exception as e:
        return ApiResponse(code=400, message=str(e))

@router.post(
    "/merge",
    summary="合并PDF",
    description="""
    将多个PDF文件合并为一个PDF文档。
    - 按上传顺序合并
    - 保持原始页面质量
    - 支持多个PDF批量合并
    """,
    response_description="返回合并后的PDF文档"
)
async def merge_pdfs(
    files: List[UploadFile] = File(
        ...,
        description="要合并的PDF文件列表",
        max_size=settings.MAX_FILE_SIZE
    )
):
    """
    合并多个PDF文件
    
    Args:
        files: 上传的PDF文件列表，每个文件大小限制10MB
    
    Returns:
        StreamingResponse: 合并后的PDF文档文件流
    
    Raises:
        400: 文件格式不支持或合并失败
    """
    try:
        # 验证所有文件
        for file in files:
            if not validate_file_type(file.filename, ['.pdf']):
                return ApiResponse(
                    code=400,
                    message=f"请上传PDF文件: {file.filename}"
                )

        contents = []
        for file in files:
            content = await file.read()
            contents.append(content)
            
        pdf_bytes = await pdf_service.merge_pdfs(contents)
        
        return StreamingResponse(
            io.BytesIO(pdf_bytes),
            media_type="application/pdf",
            headers={
                "Content-Disposition": f'attachment; filename="merged.pdf"'
            }
        )
    except Exception as e:
        return ApiResponse(code=400, message=str(e))

@router.post(
    "/split",
    summary="拆分PDF",
    description="""
    从PDF文档中提取指定页面。
    - 支持单页提取：如 "1,3,5"
    - 支持范围提取：如 "1-3,5-7"
    - 支持混合模式：如 "1-3,5,7-9"
    - 页码从1开始计数
    """,
    response_description="返回提取的PDF文档"
)
async def split_pdf(
    file: UploadFile = File(
        ...,
        description="要拆分的PDF文件",
        max_size=settings.MAX_FILE_SIZE
    ),
    page_ranges: str = "1-",
):
    """
    拆分PDF文件
    
    Args:
        file: 上传的PDF文件，大小限制10MB
        page_ranges: 要提取的页码范围，格式如："1-3,5,7-9"
    
    Returns:
        StreamingResponse: 拆分后的PDF文档文件流
    
    Raises:
        400: 文件格式不支持、页码范围无效或拆分失败
    """
    try:
        if not validate_file_type(file.filename, ['.pdf']):
            return ApiResponse(
                code=400,
                message="请上传PDF文件"
            )

        content = await file.read()
        pdf_bytes = await pdf_service.split_pdf(content, page_ranges)
        
        return StreamingResponse(
            io.BytesIO(pdf_bytes),
            media_type="application/pdf",
            headers={
                "Content-Disposition": f'attachment; filename="split.pdf"'
            }
        )
    except Exception as e:
        return ApiResponse(code=400, message=str(e)) 